package com.yunnuo.system.menu.service.impl;

import com.yunnuo.system.comm.util.*;
import com.yunnuo.system.menu.dao.IMenuDao;
import com.yunnuo.system.menu.entity.Menu;
import com.yunnuo.system.menu.service.IMenuService;
import com.yunnuo.system.role.dao.IRoleMenuDao;
import com.yunnuo.system.role.entity.Role;
import com.yunnuo.system.role.entity.RoleMenu;
import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.*;

/**
 * Created by w_weihf on 2018/8/3.
 */
@Service
public class MenuServiceImpl implements IMenuService {

    public static final String PREMISSION_STRING = "perms[\"{0}\"]";

    @Autowired
    private IMenuDao menuDao;
    @Autowired
    private IRoleMenuDao roleMenuDao;

    @Override
    public void addVO(Menu vo) throws ServiceException {
        menuDao.save(vo);
    }

    @Override
    public void updateVO(Menu vo) throws ServiceException {
        menuDao.save(vo);
    }

    @Override
    public void delList(String[] ids) throws ServiceException {
    }

    @Override
    public void deleteVo(String id) throws ServiceException {
        menuDao.delete(id);
    }

    @Override
    public List<Menu> findList() throws ServiceException {
        return menuDao.findAll();
    }

    @Override
    public List<?> findList(Menu vo, String other) throws ServiceException {
        return null;
    }



    @Override
    public Menu findVO(String id) throws ServiceException {
        return menuDao.findOne(id);
    }

    @Override
    public Set<String> selectPermsByUserId(String userId) {
        List<String> perms = menuDao.selectPermsByUserId(userId);
        Set<String> permsSet = new HashSet<String>();
        for (String perm : perms)
        {
            if (StringUtils.isNotEmpty(perm))
            {
                permsSet.addAll(Arrays.asList(perm.trim().split(",")));
            }
        }
        return permsSet;
    }

    @Override
    public Map<String, String> selectPermsAll()
    {
        LinkedHashMap section = new LinkedHashMap();
        List<Menu> permissions =   menuDao.findAll();
        if (StringUtils.isNotEmpty(permissions))
        {
            for (Menu menu : permissions)
            {
                section.put(menu.getUrl(), MessageFormat.format(PREMISSION_STRING, menu.getPerms()));
            }
        }
        return section;
    }

    @Override
    public List<Tree<Menu>> listMenuTree(String id) {
        List<Tree<Menu>> trees = new ArrayList<Tree<Menu>>();
        List<Menu> Menus = menuDao.selectAllMenuByUserId(id);
        for (Menu sysMenu : Menus) {
            Tree<Menu> tree = new Tree<Menu>();
            tree.setId(sysMenu.getId().toString());
            tree.setParentId(sysMenu.getParentId().toString());
            tree.setText(sysMenu.getMenuName());
            Map<String, Object> attributes = new HashMap<>(16);
            attributes.put("url", sysMenu.getUrl());
            attributes.put("icon", sysMenu.getIcon());
            tree.setAttributes(attributes);
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        List<Tree<Menu>> list = BuildTree.buildList(trees, "0");
        return list;
    }

    @Override
    public int selectCountMenuByParentId(String menuId) {
       List list =this.menuDao.findAllByParentId(menuId);
        if(Empty.isNotEmpty(list)){
            return list.size();
        }else{
            return 0;
        }
    }


    @Override
    public List<Map<String, Object>> roleMenuTreeData(Role role) {
        String  roleId = role.getId();
        List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>();
        List<Menu> menuList = this.menuDao.findAll();
        if (StringUtils.isNotNull(roleId))
        {
            List<RoleMenu> roleMenuList =this.roleMenuDao.findAllByRoleId(roleId);
            //将角色拥有的菜单放到集合中
            List<String> roleIds=new ArrayList<>();
            for (RoleMenu m:roleMenuList
                    ) {
                roleIds.add(m.getMenuId());
            }
           trees = getTrees(menuList, true, roleIds, true);
        }
        else
        {
            trees = getTrees(menuList, false, null, true);
        }
        return trees;
    }

    @Override
    public List<Map<String, Object>> menuTreeData() {
        List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>();
        List<Menu> menuList =this.menuDao.findAll();

        trees = getTrees(menuList, false, null, false);
        return trees;
    }

    /**
     * 根据菜单ID查询菜单信息
     * @param id
     * @return
     */
    @Override
    public Menu selectMenuById(String id) {
        return this.menuDao.findOne(id);
    }

    /**
     * 对象转菜单树
     *
     * @param menuList 菜单列表
     * @param isCheck 是否需要选中
     * @param roleMenuList 角色已存在菜单列表
     * @param permsFlag 是否需要显示权限标识
     * @return
     */
    public List<Map<String, Object>> getTrees(List<Menu> menuList, boolean isCheck, List<String> roleMenuList,
                                              boolean permsFlag)
    {
        List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>();
        for (Menu menu : menuList)
        {
            Map<String, Object> deptMap = new HashMap<String, Object>();
            deptMap.put("id", menu.getId());
            deptMap.put("pId", menu.getParentId());
            deptMap.put("name", transMenuName(menu, roleMenuList, permsFlag));
            if (isCheck)
            {
                deptMap.put("checked", roleMenuList.contains(menu.getId()));
            }
            else
            {
                deptMap.put("checked", false);
            }
            trees.add(deptMap);
        }
        return trees;
    }

    public String transMenuName(Menu menu, List<String> roleMenuList, boolean permsFlag)
    {
        StringBuffer sb = new StringBuffer();
        sb.append(menu.getMenuName());
        if (permsFlag)
        {
            sb.append("<font color=\"#888\">&nbsp;&nbsp;&nbsp;" + menu.getPerms() + "</font>");
        }
        return sb.toString();
    }
}
